import click
from flask.cli import with_appcontext
from datetime import datetime, date
from .models import Venue, VenueTimeSlot, Order, Activity
from sqlalchemy import or_
from . import db

def format_time(time_obj):
    return time_obj.strftime('%H:%M') if time_obj else 'N/A'

def format_datetime(dt_obj):
    return dt_obj.strftime('%Y-%m-%d %H:%M') if dt_obj else 'N/A'

@click.command('check-occupancy')
@with_appcontext
@click.argument('venue_id', type=int)
@click.option('--date', 'date_str', help='Date to check in YYYY-MM-DD format. Defaults to today.')
def check_occupancy_command(venue_id, date_str):
    """查询并打印指定场馆在特定日期的占用情况"""
    
    if date_str:
        try:
            date_to_check = datetime.strptime(date_str, "%Y-%m-%d").date()
        except ValueError:
            click.echo("Error: Date format must be YYYY-MM-DD.")
            return
    else:
        date_to_check = date.today()

    click.echo(f"\\n{'='*60}")
    click.echo(f"🔍 开始诊断场馆 ID: {venue_id} 在日期: {date_to_check.strftime('%Y-%m-%d')} 的占用情况")
    click.echo(f"{'='*60}")

    # 1. 查询场馆和其时间段信息
    venue = Venue.query.get(venue_id)
    if not venue:
        click.echo(f"❌ 错误：找不到ID为 {venue_id} 的场馆。")
        return

    click.echo(f"\\n--- 场馆基础信息 ---")
    click.echo(f"场馆名称: {venue.name}")
    
    day_of_week = date_to_check.isoweekday()
    time_slots = VenueTimeSlot.query.filter_by(
        venue_id=venue_id,
        day_of_week=day_of_week,
        status=1
    ).order_by(VenueTimeSlot.start_time).all()

    if not time_slots:
        click.echo("该场馆在指定日期没有可用的时间段。")
    else:
        click.echo(f"\\n--- 当日时间段及容量 ---")
        for slot in time_slots:
            click.echo(f"  - 时间段: {format_time(slot.start_time)} - {format_time(slot.end_time)}, 容量: {slot.capacity}人")
    
    # 2. 查询当天的所有相关订单
    click.echo(f"\\n--- 当日关联订单记录 (状态为 未支付、已支付、已完成) ---")
    orders = Order.query.filter(
        Order.venue_id == venue_id,
        Order.reservation_date == date_to_check,
        Order.status.in_([0, 1, 3]) # 0:未支付, 1:已支付, 3:已完成
    ).all()

    if not orders:
        click.echo("没有找到任何相关订单。")
    else:
        total_order_participants = 0
        for order in orders:
            click.echo(f"  - 订单ID: {order.id}, "
                  f"状态: {order.status_text}, "
                  f"人数: {order.participant_count}, "
                  f"时间: {format_time(order.start_time)} - {format_time(order.end_time)}, "
                  f"关联活动ID: {order.activity_id}")
            total_order_participants += order.participant_count or 1
        click.echo(f"  [小计] 订单占用总人数: {total_order_participants}")

    # 3. 查询当天的所有相关活动
    click.echo(f"\\n--- 当日关联活动记录 (状态为 open 或 closed) ---")
    start_of_day = datetime.combine(date_to_check, datetime.min.time())
    end_of_day = datetime.combine(date_to_check, datetime.max.time())

    activities = Activity.query.filter(
        Activity.venue_id == venue_id,
        Activity.status.in_(['open', 'closed']),
        or_(
            Activity.venue_start_time.between(start_of_day, end_of_day),
            Activity.venue_end_time.between(start_of_day, end_of_day),
            (Activity.venue_start_time < start_of_day) & (Activity.venue_end_time > end_of_day)
        )
    ).all()
    
    if not activities:
        click.echo("没有找到任何相关活动。")
    else:
        total_activity_participants = 0
        for activity in activities:
            occupied_by_activity = activity.max_participants or 0
            click.echo(f"  - 活动ID: {activity.id}, "
                  f"标题: '{activity.title}', "
                  f"类型: {activity.activity_type}, "
                  f"状态: {activity.status}, "
                  f"占用名额(max_participants): {occupied_by_activity}, "
                  f"时间: {format_datetime(activity.venue_start_time)} - {format_datetime(activity.venue_end_time)}")
            total_activity_participants += occupied_by_activity
        click.echo(f"  [小计] 活动占用总名额: {total_activity_participants}")
    
    click.echo(f"\\n{'='*60}")
    click.echo("🔍 诊断结束。")
    click.echo(f"{'='*60}\\n")

def init_app(app):
    app.cli.add_command(check_occupancy_command) 